package org.jeecg.modules.business.strategy.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.entity.BusBookingRooms;
import org.jeecg.modules.business.entity.BusOrderFee;
import org.jeecg.modules.business.entity.BusRoomsLivingOrder;
import org.jeecg.modules.business.enums.FeeSubjectType;
import org.jeecg.modules.business.service.IBusOrderFeeService;
import org.jeecg.modules.business.service.impl.BusBookingRoomsServiceImpl;
import org.jeecg.modules.business.strategy.PricingStrategy;
import org.jeecg.modules.rooms.Enum.ChargeTypeEnum;
import org.jeecg.modules.rooms.entity.CesAllDayPriceRule;
import org.jeecg.modules.rooms.entity.CesHourRoomRule;
import org.jeecg.modules.rooms.entity.CesHouseLongRentCharge;
import org.jeecg.modules.rooms.entity.CesRooms;
import org.jeecg.modules.rooms.service.CesRoomsServiceImpl;
import org.jeecg.modules.rooms.service.ICesHouseLongRentChargeService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Slf4j
@Component("longRentStrategy")
public class LongRentStrategy  implements PricingStrategy {
    @Resource
    IBusOrderFeeService feeService;

    @Resource
    private BusBookingRoomsServiceImpl bookingRoomsService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    ICesHouseLongRentChargeService houseLongRentChargeService;

    @Resource
    CesRoomsServiceImpl roomsService;


    @Override
    public void calculateFee(BusRoomsLivingOrder livingOrder, CesAllDayPriceRule cesAllDayPriceRule, List<CesHourRoomRule> hourRoomRuleList) {
        BusBookingRooms bookingroom = bookingRoomsService.getById(livingOrder.getBookingRoomId());
        if (ObjectUtil.isEmpty(bookingroom)){
            log.info("未找到订单{}对应的房间", livingOrder.getId());
            return;
        }
        CesRooms room = roomsService.getById(bookingroom.getRoomId());
        List<CesHouseLongRentCharge> list = houseLongRentChargeService.list(Wrappers.<CesHouseLongRentCharge>
                        lambdaQuery().eq(CesHouseLongRentCharge::getLivingOrderId, livingOrder.getId())
                .eq(CesHouseLongRentCharge::getChargeType, ChargeTypeEnum.PERIODICITY.getKey()));
        if (list.isEmpty()){
            return;
        }
        Integer cycle = list.get(0).getNum();
        List<BusOrderFee> orderFees = new ArrayList<>();
        Calendar nowCalendar = Calendar.getInstance();
        Calendar arriveCalendar = Calendar.getInstance();
        arriveCalendar.setTime(livingOrder.getArrivalTime());
        int year = nowCalendar.get(Calendar.YEAR) - arriveCalendar.get(Calendar.YEAR);
        int month = nowCalendar.get(Calendar.MONTH) - arriveCalendar.get(Calendar.MONTH);
        // 当前与入住时相距月份
        int monthDiffer = year * 12 + month;
        Calendar dueOutCalendar = Calendar.getInstance();
        dueOutCalendar.setTime(livingOrder.getDueOutTime());
        int allYear = dueOutCalendar.get(Calendar.YEAR) - arriveCalendar.get(Calendar.YEAR);
        int allMonth = dueOutCalendar.get(Calendar.MONTH) - arriveCalendar.get(Calendar.MONTH);
        // 总入住月份
        int allMonthDiffer = allYear * 12 + allMonth;
        if (monthDiffer >= allMonthDiffer){
            return;
        }
        // 下一次收费月份
        arriveCalendar.set(Calendar.YEAR, nowCalendar.get(Calendar.YEAR));
        arriveCalendar.set(Calendar.MONTH, nowCalendar.get(Calendar.MONTH));
        Integer nextMonthNum = allMonthDiffer - monthDiffer < cycle ? allMonthDiffer - monthDiffer : cycle;
        arriveCalendar.add(Calendar.MONTH, nextMonthNum);
        list.forEach(e -> {
            BusOrderFee dayOrderFee = new BusOrderFee();
            dayOrderFee.setDayTime(new Date());
            dayOrderFee.setCreateTime(new Date());
            dayOrderFee.setRemark(e.getName());
            String roomName = room.getPrefix() != null? room.getPrefix():"";
            roomName += roomName + room.getName();
            dayOrderFee.setMoney(e.getMoney());
            dayOrderFee.setSubjectType(FeeSubjectType.OTHER.getKey());
            dayOrderFee.setMoney(e.getMoney().multiply(BigDecimal.valueOf(nextMonthNum)));
            if (e.getIsMust() != null && e.getIsMust()){
                dayOrderFee.setSubjectType(FeeSubjectType.MEI_RI_FANG_FEI.getKey());
                dayOrderFee.setRemark(DateUtil.format(new Date(), "yyyy-MM") + e.getName());
            }
            dayOrderFee.setFeeType(1);
            dayOrderFee.setRoomId(room.getId());
            dayOrderFee.setLivingOrderId(livingOrder.getId());
            dayOrderFee.setHotelId(room.getHotelId());
            orderFees.add(dayOrderFee);
        });
        feeService.saveBatch(orderFees);
        redisTemplate.opsForZSet().remove("overTimerOrder",livingOrder.getId());
        redisTemplate.opsForZSet().add("overTimerOrder",livingOrder.getId(), arriveCalendar.getTimeInMillis());

    }
}
